namespace AltNetUK.Models
{
    using System;
    using System.Collections.Specialized;
    using System.Diagnostics.CodeAnalysis;
    using System.Web.Mvc;
    using System.Xml.Serialization;
    using AltNetUK.Models.Inputs;
    using SimpleWebServices.Configuration;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web;
    using System.Net.Mail;
    using System.Text;
    using System.Globalization;

    [XmlRoot(ElementName = "form")]
    public sealed class RegistrationForm : Resource, IModelBinder
    {
        private Registration _data;
        private Registrations _altnetbeers;
        private Registrations _altnetconf;
        private Registrations _openspacecode;
        private static readonly CheckBox _altnetbeersControl = new CheckBox()
        {
            AccessKey = 'b',
            Id = "altnetbeers",
            Name = "altnetbeers",
            Title = "<strong>Alt.Net Beers</strong> on Friday 31 July 2009"
        };
        private static readonly CheckBox _altnetconfControl = new CheckBox()
        {
            AccessKey = 'a',
            Id = "altnetconf",
            Name = "altnetconf",
            Title = "<strong>Alt.Net Conference Day</strong> on Sunday 2 August 2009"
        };
        private static readonly CheckBox _openspacecodeControl = new CheckBox()
        {
            AccessKey = 'c',
            Id = "openspacecode",
            Name = "openspacecode",
            Title = "<strong>Open Space Coding Day</strong> on Saturday 1 August 2009"
        };
        private static readonly TextInput _emailControl = new TextInput(new EmailValidator())
        {
            AccessKey = 'e',
            Id = "email",
            MaxLength = 255,
            Name = "email",
            Required = true,
            Title = "Your email address"
        };
        private static readonly TextArea _messageControl = new TextArea(new StringValidator())
        {
            AccessKey = 'm',
            Id = "message",
            Name = "message",
            Required = false,
            Title = "Any message"
        };
        private static readonly TextInput _nameControl = new TextInput(new StringValidator() { MinLength = 1 })
        {
            AccessKey = 'n',
            Id = "name",
            MaxLength = 255,
            Name = "name",
            Required = true,
            Title = "Your name"
        };
        private static readonly TextInput _twitterControl = new TextInput(new StringValidator())
        {
            AccessKey = 't',
            Id = "twitter",
            MaxLength = 50,
            Name = "twitter",
            Required = false,
            Title = "Your twittername"
        };

        public static RegistrationForm Load(string identifier)
        {
            return Load((null == identifier) ? Guid.Empty : new Guid(identifier));
        }

        public static RegistrationForm Load(Guid identifier)
        {
            RegistrationForm result = new Default().Object<RegistrationForm>();

            if (Guid.Empty == identifier)
            {
                result.Data = new Registration();
                result.Data.AltNetConference = !new Registrations("altnetconf").IsFull;
            }
            else
            {
                result.Data = Repository.Select<Registration>(identifier) ?? new Registration();
            }

            return result;
        }

        [XmlIgnore]
        public static CheckBox AltNetBeersControl
        {
            get
            {
                return _altnetbeersControl;
            }
        }

        [XmlIgnore]
        public static CheckBox AltNetConferenceControl
        {
            get
            {
                return _altnetconfControl;
            }
        }

        [XmlIgnore]
        public static CheckBox OpenSpaceCodingControl
        {
            get
            {
                return _openspacecodeControl;
            }
        }

        [XmlIgnore]
        public static TextInput EmailControl
        {
            get
            {
                return _emailControl;
            }
        }

        [XmlIgnore]
        public static TextArea MessageControl
        {
            get
            {
                return _messageControl;
            }
        }

        [XmlIgnore]
        public static TextInput NameControl
        {
            get
            {
                return _nameControl;
            }
        }

        [XmlIgnore]
        public static TextInput TwitterControl
        {
            get
            {
                return _twitterControl;
            }
        }

        [XmlIgnore]
        public bool DisplayForm
        {
            get
            {
                return !(this.AltNetBeers.IsFull && this.AltNetConference.IsFull && this.OpenSpaceCoding.IsFull);
            }
        }

        [XmlIgnore]
        public Registrations AltNetBeers
        {
            get
            {
                if (null == this._altnetbeers)
                {
                    this._altnetbeers = new Registrations("altnetbeers");
                }

                return this._altnetbeers;
            }
        }

        [XmlIgnore]
        public Registrations AltNetConference
        {
            get
            {
                if (null == this._altnetconf)
                {
                    this._altnetconf = new Registrations("altnetconf");
                }

                return this._altnetconf;
            }
        }

        [XmlIgnore]
        public Registrations OpenSpaceCoding
        {
            get
            {
                if (null == this._openspacecode)
                {
                    this._openspacecode = new Registrations("openspacecode");
                }

                return this._openspacecode;
            }
        }

        [XmlIgnore]
        public bool IsValid
        {
            get
            {
                return RegistrationForm.EmailControl.Validate(this.Data.Email).IsValid &&
                    RegistrationForm.NameControl.Validate(this.Data.Name).IsValid &&
                    RegistrationForm.TwitterControl.Validate(this.Data.Twitter).IsValid;
            }
        }

        [XmlIgnore]
        public Registration Data
        {
            get
            {
                return this._data;
            }

            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("value");
                }

                this._data = value;
            }
        }

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (null == controllerContext)
            {
                throw new ArgumentNullException("controllerContext");
            }

            NameValueCollection form = controllerContext.HttpContext.Request.Form;

            Registration data = new Registration()
            {
                AltNetBeers = "on".Equals(form["altnetbeers"], StringComparison.OrdinalIgnoreCase),
                AltNetConference = "on".Equals(form["altnetconf"], StringComparison.OrdinalIgnoreCase),
                Email = form["email"],
                Name = form["name"],
                Twitter = form["twitter"],
                Message = form["message"],
                OpenSpaceCoding = "on".Equals(form["openspacecode"], StringComparison.OrdinalIgnoreCase)
            };

            if (!string.IsNullOrEmpty(form["unique"]))
            {
                (data as IPersistable).Unique = new Guid(form["unique"]);
            }

            return new RegistrationForm()
            {
                Data = data
            };
        }

        public void Store()
        {
            if (!string.IsNullOrEmpty(this.Data.Twitter) && this.Data.Twitter.StartsWith("@", StringComparison.OrdinalIgnoreCase))
            {
                this.Data.Twitter = this.Data.Twitter.Substring(1);
            }

            this.Data.Complete = this.IsValid;
            if (null == (this.Data as IPersistable).Identifier)
            {
                (this.Data as IPersistable).Identifier = new Uri("http://www.altnetuk.com/registration/" + Guid.NewGuid().ToString());
            }

            //(this.Data as IPersistable).Unique = (Repository.Upsert<Registration>(this.Data) as IPersistable).Unique;
            this.Data = Repository.Upsert<Registration>(this.Data);
            if (this.Data.Complete)
            {
                new AttendeeEmail(this.Data).Send();
                new AdministrationEmail(this.Data).Send();
            }
        }
    }
}